package com.example.sample.activity;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.app.usage.UsageStats;
import android.app.usage.UsageStatsManager;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.Process;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import org.w3c.dom.Text;

import com.example.app.BaseActivity;
import com.example.sample.R;
import com.example.sample.R.id;
import com.example.sample.R.layout;

import net.liteheaven.xblib.common.ui.ToastUtil;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

public class ProcessInfoActivity extends BaseActivity {

    private ListView mListView;
    private PiAdapter mAdapter;
    private TextView tv1;
    private TextView tv2;
    private CheckBox checkbox;
    private List<ProcessInfoModel> piList = new ArrayList<ProcessInfoModel>();

    private class PiItem extends LinearLayout{

        public TextView processName;
        public TextView uid;
        public TextView pid;
        public TextView pkg;
        public TextView imp;

        public PiItem(Context context) {
            super(context);
            init();
        }

        public PiItem(Context context, AttributeSet attrs) {
            super(context, attrs);
            init();
        }

        public PiItem(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init();
        }

        private void init(){
            LayoutInflater li = getLayoutInflater();
            li.inflate(R.layout.item_process_info, this);
            processName = (TextView)findViewById(R.id.tvName);
            pid = (TextView)findViewById(R.id.tvPid);
            uid = (TextView)findViewById(R.id.tvUid);
            imp = (TextView)findViewById(R.id.tvImportance);
            pkg = (TextView)findViewById(R.id.tvPkg);
        }
    }

    private class PiAdapter extends BaseAdapter{

        @Override
        public int getCount() {
            return piList.size();
        }

        @Override
        public Object getItem(int position) {
            return null;
        }

        @Override
        public long getItemId(int position) {
            return 0;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            PiItem v = null;
            if (convertView == null){
                v = new PiItem(getApplicationContext());
            }else{
                v = (PiItem)convertView;
            }

            ProcessInfoModel pi = piList.get(position);
            v.processName.setText(""+pi.getProcessName());
            v.imp.setText(""+pi.getImportance());
            v.pid.setText(""+pi.getPid());
            v.uid.setText(""+pi.getUid());
            v.pkg.setText(pi.getPackageName());
            return v;
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_process_info);
        mListView = (ListView)findViewById(R.id.lvProcess);
        mAdapter = new PiAdapter();
        mListView.setAdapter(mAdapter);
        tv1 = (TextView) findViewById(R.id.tv1);
        tv2 = (TextView) findViewById(R.id.tv2);
        checkbox = (CheckBox) findViewById(R.id.checkbox);
        checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                update(isChecked);
            }
        });
        checkbox.setChecked(true);
    }

    private void update(boolean ams){
        getProcessList(ams);
        mAdapter.notifyDataSetChanged();

        tv1.setText("AMS方式：\n" + getProcessNameByAms(this));
        tv2.setText("proc方式：\n" + getProcessNameByProc());
    }

    private List<ProcessInfoModel> getByAms(){
        long start = System.currentTimeMillis();
        ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
        List<RunningAppProcessInfo> piList = am.getRunningAppProcesses();
        long interval = System.currentTimeMillis() - start;
        Log.i("ProcessInfoActivity", "getRunningAppProcesses interval = " + interval);

        List<ProcessInfoModel> newList = new ArrayList<ProcessInfoModel>();
        for (RunningAppProcessInfo pi : piList){
            newList.add(new AMSPi(pi));
        }
        return newList;
    }

    private List<ProcessInfoModel> getByUsm(){
        if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP) {
            return new ArrayList<ProcessInfoModel>();
        }

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        long endTime = calendar.getTimeInMillis();//结束时间
        calendar.add(Calendar.DAY_OF_MONTH, -1);//时间间隔为一个月
        long startTime = calendar.getTimeInMillis();//开始时间
        UsageStatsManager usageStatsManager = (UsageStatsManager) getSystemService(USAGE_STATS_SERVICE);
        //获取一个月内的信息
        List<UsageStats> queryUsageStats = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_YEARLY, startTime, endTime);

        if (queryUsageStats.isEmpty()){
            try {
                startActivity(new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS));
            } catch (Exception e) {
                ToastUtil.show(this,"无法开启允许查看使用情况的应用界面");
                e.printStackTrace();
            }
        }

        List<ProcessInfoModel> newList = new ArrayList<ProcessInfoModel>();
        for (UsageStats us : queryUsageStats) {
            newList.add(new USMPi(us));
        }
        return newList;
    }

    private void getProcessList(boolean ams){
        if (ams){
            piList = getByAms();
        }else{
            piList = getByUsm();
        }
    }

    private String getProcessNameByAms(Context context){
        // get by ams
        ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> processes = manager.getRunningAppProcesses();
        if (processes != null) {
            int pid = android.os.Process.myPid();
            for (ActivityManager.RunningAppProcessInfo processInfo : manager.getRunningAppProcesses()) {
                if (processInfo.pid == pid && !TextUtils.isEmpty(processInfo.processName)) {
                    return processInfo.processName;
                }
            }
        }
        return "";
    }

    private String getProcessNameByProc() {
        BufferedReader br = null;
        boolean undone = false;

        String result;
        label97:
        {
            try {
                undone = true;
                int var1 = Process.myPid();
                result = "/proc/" + var1 + "/cmdline";
                br = new BufferedReader(new InputStreamReader(new FileInputStream(result), "iso-8859-1"));
                StringBuilder sb = new StringBuilder();

                while ((var1 = br.read()) > 0) {
                    sb.append((char) var1);
                }

                result = sb.toString();
                undone = false;
                break label97;
            } catch (Exception e) {
                undone = false;
            } finally {
                if (undone) {
                    if (br != null) {
                        try {
                            br.close();
                        } catch (IOException var9) {
                            var9.printStackTrace();
                        }
                    }

                }
            }

            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            return null;
        }

        try {
            br.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return result;
    }

    public interface ProcessInfoModel{
        String getProcessName();
        String getImportance();
        String getPid();
        String getUid();
        String getPackageName();
    }

    /**
     * activity manager service 方式获取的进程信息
     */
    public static class AMSPi implements ProcessInfoModel{

        private RunningAppProcessInfo pi;

        public AMSPi(RunningAppProcessInfo pi){
            this.pi = pi;
        }

        @Override
        public String getProcessName() {
            return pi.processName;
        }

        @Override
        public String getImportance() {
            return "" + pi.importance;
        }

        @Override
        public String getPid() {
            return "" + pi.pid;
        }

        @Override
        public String getUid() {
            return "" + pi.uid;
        }

        @Override
        public String getPackageName() {
            StringBuffer pkgTxt = new StringBuffer();
            for (int i = 0; i<pi.pkgList.length; i++){
                pkgTxt.append(pi.pkgList[i]);
                if (i < pi.pkgList.length-1){
                    pkgTxt.append("\n");
                }
            }
            return pkgTxt.toString();
        }
    }

    /**
     * UsageStatsManager方式获取的进程信息
     */
    public static class USMPi implements ProcessInfoModel{

        private UsageStats us;

        public USMPi(UsageStats us){
            this.us = us;
        }

        @Override
        public String getProcessName() {
            return "getProcessName";
        }

        @Override
        public String getImportance() {
            return "getImportance";
        }

        @Override
        public String getPid() {
            return "getPid";
        }

        @Override
        public String getUid() {
            return "getUid";
        }

        @Override
        public String getPackageName() {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                return us.getPackageName();
            }
            return "";
        }
    }
}
